package com.iwhalecloud.bss.kite.cucc.service.pos.handler.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.common.constant.ServiceOfferConsts;
import com.iwhalecloud.bss.kite.common.util.KiteDateUtils;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosRelationDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosUserDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.CuccServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.ExtOrderInfoCache;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.IKitePosSceneHandler;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.KitePosHandlerContext;
import com.iwhalecloud.bss.kite.cucc.service.util.ChangeTypeUtils;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.ztesoft.bss.common.util.SpringUtil;

@Service
public class KitePosRelationHandler extends KitePosBaseRelationHandler implements IKitePosSceneHandler {

    @Override
    public void handle(KitePosHandlerContext context) {
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(context.getSceneInstId());
        // 延期不需要传relation
        if (KiteStringUtils.equalsAny(sceneInst.getServiceOfferId(), LocalServiceOfferConsts.SERVICE_OFFER_COP_MEMBER_QUIT, LocalServiceOfferConsts.SERVICE_OFFER_COP_MEMBER_JOIN)) {
            return;
        }

        // 追加订购订单修改,重提环节的,不重新组装，直接用订单接口返回的。
        if (KiteStringUtils.isEqual(sceneInst.getServiceOfferId(), ServiceOfferConsts.SERVICE_OFFER_ORDER)
            && KiteStringUtils.equals(CuccServiceOfferConsts.SERVICE_OFFER_ADD_ORDER, sceneInst.getOperType())
            && sceneInst.getAskSource().equals(LocalKeyConsts.ASK_SOURCE_ORDER)) {
            KitePosDTO infOrderDto = ExtOrderInfoCache.get(sceneInst.getSceneInstId());
            if (!KiteObjectUtils.isEmpty(infOrderDto) && KiteListUtils.isNotEmpty(infOrderDto.getRelations())) {
                context.getPosDto().setRelations(infOrderDto.getRelations());
                return;
            }
        }

        if (CuccPosServiceUtils.needPackageRelations(context.getSceneInstId(), context.getCustId())) {
            KiteOfferInst offerInst = querySceneInstService.getOfferInst(context.getCustId(), sceneInst.getRootInstId());
            List<KitePosRelationDTO> relations = Lists.newArrayList();

            relations.addAll(packageRelations(context.getSceneInstId(), offerInst, context.getPosDto().getUsers(),
                context.getPosDto().getRelations(), sceneInst));
            context.getPosDto().setRelations(relations);
        }/*else{ // modified by ma.junjun 2022-01-29 物联网融合bug 处理
            List<KitePosRelationDTO> relations =  context.getPosDto().getRelations();
            if(KiteListUtils.isNotEmpty(relations)){
                relations.stream().forEach(relation->{
                    relation.setUserInstId(relation.getMemUserId());
                    relation.setMemUserId(null);
                    relation.setInstanceId(this.genInstanceId(relation.getInstanceId(), context.getPosDto().getRelations()));
                    relation.setChangeType(ChangeTypeUtils.CHANGE_TYPE_K);
                });
                context.getPosDto().setRelations(relations);
            }
        }*/
    }

    private List<KitePosRelationDTO> packageRelations(String sceneInstId, KiteOfferInst offerInst,
        List<KitePosUserDTO> users, List<KitePosRelationDTO> oldRelations, KiteSceneInst sceneInst) {
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        KiteSceneInst kiteSceneInst = querySceneInstService.getSceneInst(sceneInstId);
        List<KitePosRelationDTO> relations = Lists.newArrayList();
        String business_number = querySceneInstService.getCommonAttrValue(sceneInstId, "business_number");
        String primaryUserId = users.stream().filter(user -> business_number.equals(user.getSerialNumber())).findAny()
            .map(KitePosUserDTO::getUserId).orElse("");
        String primaryUserInstId = users.stream().filter(user -> business_number.equals(user.getSerialNumber())).findAny()
            .map(KitePosUserDTO::getInstanceId).orElse("");
        List<Map<String, Object>> groupUserInfos = null;
        // 收入归集集团成员加入和退出，这里取集团号码
        if (KiteStringUtils.equalsAny(kiteSceneInst.getServiceOfferId(), LocalServiceOfferConsts.SERVICE_OFFER_COLLECTION_GROUP_ADD)) {
            List<KitePosUserDTO> userList = (List<KitePosUserDTO>) querySceneInstService.getExtParameterValue(sceneInstId, "serialNumber");
            primaryUserId = userList.stream().filter(user -> business_number.equals(user.getSerialNumber())).findAny()
                .map(KitePosUserDTO::getUserId).orElse("");
            if (KiteStringUtils.isEmpty(primaryUserId)) {
                primaryUserId = querySceneInstService.getCommonAttrValue(sceneInstId, "PRIMARY_USER_ID");
            }
            primaryUserInstId = userList.stream().filter(user -> business_number.equals(user.getSerialNumber())).findAny()
                .map(KitePosUserDTO::getInstanceId).orElse("");
        }
        else if (KiteStringUtils.equals(kiteSceneInst.getServiceOfferId(), LocalServiceOfferConsts.SERVICE_OFFER_COLLECTION_GROUP_DEL)) {
            groupUserInfos = querySceneInstService.getExtParameterValue(sceneInstId, "delGroupUserInfos");
        }

        int index = 1;
        List<Map<String, Object>> relationRoleList = queryRelation(sceneInstId, "1");
        for (KitePosUserDTO userDto : users) {
            if (KiteStringUtils.equals(userDto.getUserId(), primaryUserId)) {
                userDto.setUserDiffCode(KiteMapUtils.getString(relationRoleList.get(0), "RELATION_TYPE_CODE"));
            }
            // 不跟自己建群组关系
            if (KiteStringUtils.equals(userDto.getSerialNumber(), business_number)) {
                continue;
            }
            KitePosRelationDTO relationDto = new KitePosRelationDTO();

            List<Map<String, Object>> relationRoles = relationRoleList.stream().filter(role -> (
                KiteStringUtils.equals((String) role.get("MEM_GOODS_CLASSIFY_ID"), userDto.getOfferCatagoryId())
                    || KiteStringUtils.equals((String) role.get("MEM_GOODS_CLASSIFY_ID"), "-1")))
                .collect(Collectors.toList());
            if (!KiteListUtils.isEmpty(relationRoles)) {
                Map relationRole = relationRoles.get(0);
                relationDto.setRelationTypeCode(KiteMapUtils.getString(relationRole, "RELATION_TYPE_CODE"));
                relationDto.setPrimaryRoleCode(KiteMapUtils.getString(relationRole, "PRIMARY_ROLE_CODE"));
                relationDto.setMemRoleCode(KiteMapUtils.getString(relationRole, "MEM_ROLE_CODE"));

                if (KiteStringUtils.equalsAny(sceneInst.getServiceOfferId(), LocalServiceOfferConsts.SERVICE_OFFER_COLLECTION_GROUP_ADD)){
                    Date createDate = sceneInst.getCreateDate();
                    relationDto.setStartTime(KiteDateUtils.formatDate(createDate, KiteDateUtils.DATE_TIME_FORMAT_14));
                }else{
                    relationDto.setStartTime(userDto.getOpenDate());
                }

                if (KiteStringUtils.equals(kiteSceneInst.getServiceOfferId(),
                    LocalServiceOfferConsts.SERVICE_OFFER_COLLECTION_GROUP_DEL) && KiteListUtils
                    .isNotEmpty(groupUserInfos)) {
                    Map<String, Object> tempMap = groupUserInfos.stream().filter(map -> KiteStringUtils
                        .equals(KiteMapUtils.getString(map, "MEM_SERIAL_NUMBER"), userDto.getSerialNumber()))
                        .findFirst().orElse(null);
                    relationDto.setPrimaryUserId(KiteMapUtils.getString(tempMap, "PRIMARY_USER_ID"));
                    relationDto.setPrimarySerialNumber(KiteMapUtils.getString(tempMap, "PRIMARY_SERIAL_NUMBER"));
                }
                else {
                    relationDto.setPrimarySerialNumber(business_number);
                    relationDto.setPrimaryUserId(primaryUserId);
                    relationDto.setEndTime(KiteMapUtils.getString(relationRole, "END_DATE"));
                }
                relationDto.setUserInstId(userDto.getInstanceId());
                relationDto.setPrimaryProvinceCode(userDto.getProvinceCode());
                relationDto.setPrimaryEparchyCode(userDto.getCityCode());
                relationDto.setDiscntPriority(String.valueOf(index));
                relationDto.setChangeType(userDto.getChangeType());

                if (KiteStringUtils.equalsAny(kiteSceneInst.getServiceOfferId(), LocalServiceOfferConsts.SERVICE_OFFER_COLLECTION_GROUP_ADD)) {
                    relationDto.setChangeType(ChangeTypeUtils.CHANGE_TYPE_A);
                }
                else if (KiteStringUtils.equalsAny(kiteSceneInst.getServiceOfferId(), LocalServiceOfferConsts.SERVICE_OFFER_COLLECTION_GROUP_DEL)) {
                    relationDto.setChangeType(ChangeTypeUtils.CHANGE_TYPE_D);
                    relationDto.setEndTime(KiteDateUtils.formatDate(new Date(),KiteDateUtils.DATE_TIME_FORMAT_14));
                }
                relationDto.setInstanceId(this.genInstanceId(userDto.getInstanceId(), oldRelations));

                relations.add(relationDto);

                index++;
            }
        }

        // 追加订购业务,relations补充追加订购主副卡关系
        KitePosUserDTO oldUser = null;
        if (KiteStringUtils.isEqual(sceneInst.getServiceOfferId(), ServiceOfferConsts.SERVICE_OFFER_ORDER)
            && KiteStringUtils.equals("1008", sceneInst.getOperType())) {
            List<Map<String, Object>> relationList = queryRelation(sceneInstId, "3");
            KitePosDTO infOrderDto = ExtOrderInfoCache.get(sceneInstId);
            if (!KiteObjectUtils.isEmpty(infOrderDto) && KiteListUtils.isNotEmpty(infOrderDto.getUsers())) {
                oldUser = infOrderDto.getUsers().stream()
                    .filter(user -> !KiteStringUtils.isEqual("-1", user.getUserDiffCode())).findFirst().orElse(null);
            }
            if (KiteListUtils.isNotEmpty(relationList)) {
                for (Map relationRole : relationList) {
                    KitePosRelationDTO relationDto = new KitePosRelationDTO();
                    relationDto.setRelationTypeCode(KiteMapUtils.getString(relationRole, "RELATION_TYPE_CODE"));
                    relationDto.setPrimaryRoleCode(KiteMapUtils.getString(relationRole, "PRIMARY_ROLE_CODE"));
                    relationDto.setMemRoleCode(KiteMapUtils.getString(relationRole, "MEM_ROLE_CODE"));
                    relationDto.setStartTime(oldUser.getOpenDate());
                    relationDto.setEndTime(KiteMapUtils.getString(relationRole, "END_DATE"));
                    relationDto.setUserInstId(primaryUserInstId);
                    relationDto.setPrimaryUserId(oldUser.getUserId());
                    relationDto.setPrimarySerialNumber(oldUser.getSerialNumber());
                    relationDto.setPrimaryProvinceCode(oldUser.getProvinceCode());
                    relationDto.setPrimaryEparchyCode(oldUser.getCityCode());
                    relationDto.setDiscntPriority(String.valueOf(index));
                    relationDto.setChangeType(
                        KiteStringUtils.isEmpty(oldUser.getChangeType()) ? "0" : oldUser.getChangeType());
                    relationDto.setInstanceId(this.genInstanceId(oldUser.getInstanceId(), oldRelations));
                    relations.add(relationDto);
                    index++;
                }
            }
        }
        return relations;
    }
}
